using System;
using System.Collections.Generic;

namespace CombatTracker.Creatures
{
  public class CreatureList : List<Creature>
  {
    public event CreatureListEvent ListChanged;

    public InitiativeList RollInitiative()
    {
      InitiativeList result = new InitiativeList();

      foreach (Creature creature in this)
      {
        creature.RollInitiative();
      }

      Sort();

      foreach (Creature creature in this)
      {
        result.AddLast(creature);
      }

      return result;
    }

    public void TakeOutOfCombat()
    {
      foreach (Creature creature in this)
      {
        creature.InitiativeStatus = InitiativeState.OutOfCombat;
      }
    }

    public void AddInitiativeRollListener(CreatureEvent listener)
    {
      foreach (Creature creature in this)
      {
        creature.RollForInitiative += listener;
      }
    }

    public void RemoveInitiativeRollListener(CreatureEvent listener)
    {
      foreach (Creature creature in this)
      {
        creature.RollForInitiative -= listener;
      }
    }

    private void OnListChanged()
    {
      if (ListChanged != null)
      {
        ListChanged.Invoke(this);
      }
    }

    #region ListChanged Shadow Functions

    public new void Add(Creature item)
    {
      base.Add(item);
      OnListChanged();
    }

    public new void AddRange(IEnumerable<Creature> items)
    {
      base.AddRange(items);
      OnListChanged();
    }

    public new void Insert(int index, Creature item)
    {
      base.Insert(index, item);
      OnListChanged();
    }

    public new void InsertRange(int index, IEnumerable<Creature> items)
    {
      base.InsertRange(index, items);
      OnListChanged();
    }

    public new void Remove(Creature item)
    {
      base.Remove(item);
      OnListChanged();
    }

    public new void RemoveAt(int index)
    {
      base.RemoveAt(index);
      OnListChanged();
    }

    public new void RemoveRange(int index, int count)
    {
      base.RemoveRange(index, count);
      OnListChanged();
    }

    public new void RemoveAll(Predicate<Creature> match)
    {
      base.RemoveAll(match);
      OnListChanged();
    }

    public new void Clear()
    {
      base.Clear();
      OnListChanged();
    }
    #endregion
  }

  public delegate void CreatureListEvent(CreatureList sender);
}